import { cosmiconfigSync } from 'cosmiconfig';
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
import { join } from 'node:path';
import { homedir } from 'node:os';
import type { CLIConfig } from '../types/index.js';

const DEFAULT_CONFIG: CLIConfig = {
  plugins: [],
  logLevel: 'info',
  theme: {
    primary: '#007acc',
    secondary: '#6c757d',
    success: '#28a745',
    warning: '#ffc107',
    error: '#dc3545',
  },
};

export class ConfigManager {
  private config: CLIConfig;
  private configPath: string;

  constructor(configPath?: string) {
    this.configPath = configPath || join(homedir(), '.genwavejs', 'config.json');
    this.config = this.loadConfig();
  }

  private loadConfig(): CLIConfig {
    try {
      // Try to load from cosmiconfig first (project-level config)
      const explorer = cosmiconfigSync('genwavejs');
      const result = explorer.search();
      
      if (result && result.config) {
        return { ...DEFAULT_CONFIG, ...result.config };
      }

      // Fallback to global config file
      if (existsSync(this.configPath)) {
        const configContent = readFileSync(this.configPath, 'utf-8');
        const userConfig = JSON.parse(configContent);
        return { ...DEFAULT_CONFIG, ...userConfig };
      }

      return DEFAULT_CONFIG;
    } catch (error) {
      console.warn('Failed to load config, using defaults:', error);
      return DEFAULT_CONFIG;
    }
  }

  public getConfig(): CLIConfig {
    return { ...this.config };
  }

  public updateConfig(updates: Partial<CLIConfig>): void {
    this.config = { ...this.config, ...updates };
    this.saveConfig();
  }

  public resetConfig(): void {
    this.config = { ...DEFAULT_CONFIG };
    this.saveConfig();
  }

  private saveConfig(): void {
    try {
      const configDir = join(this.configPath, '..');
      if (!existsSync(configDir)) {
        import('fs-extra').then(fs => {
          fs.ensureDirSync(configDir);
        });
      }

      writeFileSync(this.configPath, JSON.stringify(this.config, null, 2));
    } catch (error) {
      console.error('Failed to save config:', error);
    }
  }

  public getConfigPath(): string {
    return this.configPath;
  }
}

export const createConfigManager = (configPath?: string): ConfigManager => {
  return new ConfigManager(configPath);
};
